package org.flexthinker.binding.ui.form.binding.support
{
    import flash.display.DisplayObject;

    import org.flexthinker.binding.bean.Binding;
    import org.flexthinker.binding.form.FormModel;

    import org.flexthinker.binding.ui.form.binding.Binder;

    /**
     * Abstract implementation of <code> Binder </code>.
     *
     * @see org.flexthinker.binding.ui.form.binding.Binder
     */
    public class AbstractBinder implements Binder
    {
        private var component:DisplayObject;
        private var formProperty:String;
        private var formModel:FormModel;

        public function AbstractBinder(component:DisplayObject, formProperty:String):void
        {
            Binder(component, formProperty);
        }

        public function getBinding(formModel:FormModel):Binding
        {
            this.formModel = formModel;
            throwIfInvalidFormModel();
            return getAutoBinding();
        }

        public function getComponent():DisplayObject
        {
            return component;
        }


        public function getFormProperty():String
        {
            return formProperty;
        }

        // --------------------
        //   internal methods
        // --------------------

        internal function Binder(component:DisplayObject, formProperty:String):void
        {
            if ( component == null )
            {
                throw new ArgumentError("Please provide a non-null component. Can't create Binder on a null component instance");
            }
            if ( formProperty == null || (formProperty && formProperty.length == 0 ))
            {
                throw new ArgumentError("Please provide a proper formProperty. Can't create binding on a null or empty formProperty.")
            }
            this.component = component;
            this.formProperty = formProperty;
        }

        protected function getAutoBinding():Binding
        {
            throw new Error("Subclasses must implement this method.");
        }

        private function throwIfInvalidFormModel():void
        {
            if ( formModel == null )
            {
                throw new Error("Please provided a non-null FormModel to this Binder")
            }
        }

        protected function getFormModel():FormModel
        {
            return formModel;
        }
    }
}
